package config

import (
	"cloud_worm/util/uconfig"
	"fmt"
	"sync"
	"encoding/json"
	"github.com/golang/glog"
	"cloud_worm/util/unet"
	"strings"
)

type ConfInfo struct {
	RunMode 	string		`json:"run_mode"`

	LocalNet 	string			`json:"local_net"`			// 本地地址的网段采用逗号分割
	LocalAddr 	string		`json:"local_addr"`

	Mysql		MysqlConfig		`json:"mysql"`
	Server 		ServerConfig 	`json:"server"`
	LocalConfig	LocalConfig		`json:"local_config"`
	TLSCertInfo TLSCertInfo		`json:"tls_cert_info"`
	
	GrayConfig 	GrayInfo		`json:"gray_config"`
}

func (c *ConfInfo) ReadConfig(fileName string) error {
	config := uconfig.InitConfig{}
	container, err := config.Parse(fileName)
	if err != nil {
		return err
	}

	c.RunMode = container.String("run_mode")
	if c.RunMode == "" {
		return fmt.Errorf("no run_mode exist")
	}

	c.LocalNet = container.String("local_net")
	if c.LocalNet == "" {
		return fmt.Errorf("no local_net exist")
	}

	if err := c.Mysql.parse(container); err != nil {
		return err
	}
	if err := c.Server.parse(container); err != nil {
		return err
	}
	if err := c.LocalConfig.parse(container); err != nil {
		return err
	}
	if err := c.TLSCertInfo.parse(container); err != nil {
		return err
	}
	if err := c.GrayConfig.parse(container); err != nil {
		return err
	}

	return nil
}

var ConfInst *ConfInfo
var confOnce sync.Once

func init()  {
	confOnce.Do(func() {
		ConfInst = &ConfInfo{}
	})
}

func LoadConfig(fileName string) error {
	err := ConfInst.ReadConfig(fileName)
	if err != nil {
		return err
	}

	SetLocalAddrFilter(ConfInst.LocalNet)
	ConfInst.LocalAddr = LocalIP()
	if ConfInst.LocalAddr == "" {
		return fmt.Errorf("local ip get error")
	}

	data, _ := json.Marshal(ConfInst)
	glog.Infof(string(data))
	return nil
}


func LocalIP() string {

	ips, err := unet.AllIPs()
	if err != nil {
		glog.Errorf("lookup all ips error: %s", err.Error())
		return ""
	}

	return unet.Intranet(ips)
}

// TODO：添加其他的规则
func SetLocalAddrFilter(localNet string)  {

	for _, item := range strings.Split(localNet, ";") {
		item := strings.TrimSpace(item)
		if len(item) == 0 {
			continue
		}

		filterFunc := func(input string) bool {
			if strings.HasPrefix(input, item) {
				return true
			}
			return false
		}
		unet.RegisterParser(item, filterFunc)
	}

	return
}